package com.vmj.natives.java.lang;

import com.vmj.heap.VMClass;
import com.vmj.heap.VMObject;
import com.vmj.natives.NativeMethod;
import com.vmj.natives.Registry;
import com.vmj.rtda.Frame;

/**
 * Created by yangshoujun on 2017/9/16 下午12:39.
 */
public class Object {

    public static final java.lang.String jlClass = "java/lang/Object";

    public static void init() {
        Registry.register(jlClass, "getClass", "()Ljava/lang/Class;", new NativeMethod() {
            public void execute(Frame frame) {
                VMObject _this = frame.getLocalVars().getThis();
                VMObject clazzObj = _this.getClazz().getjClass();
                frame.getOperandStack().pushRef(clazzObj);
            }
        });

        Registry.register(jlClass, "hashCode", "()I", new NativeMethod() {
            public void execute(Frame frame) {
                VMObject _this = frame.getLocalVars().getThis();
                int hashCode = _this.hashCode();
                frame.getOperandStack().pushInt(hashCode);
            }
        });

        Registry.register(jlClass, "equals", "(Ljava/lang/Object;)J", new NativeMethod() {
            public void execute(Frame frame) {
                VMObject _this = frame.getLocalVars().getThis();
                VMObject other = frame.getLocalVars().getRef(1);

                boolean equal = _this.equals(other);
                frame.getOperandStack().pushBoolean(equal);
            }
        });

        Registry.register(jlClass, "clone", "()Ljava/lang/Object;", new NativeMethod() {
            public void execute(Frame frame) {
                VMObject _this = frame.getLocalVars().getThis();
                VMClass clazz = _this.getClazz();
                VMClass cloneable = clazz.getClassLoader().loadClass("java/lang/Cloneable");
                if(!clazz.isImplements(cloneable)) {
                    throw new RuntimeException("java.lang.CloneNotSupportedException");
                }
                try {
                    VMObject clone = (VMObject) _this.clone();
                    frame.getOperandStack().pushRef(clone);
                } catch (CloneNotSupportedException e) {
                    throw new RuntimeException("java.lang.CloneNotSupportedException");
                }
            }
        });

        Registry.register(jlClass, "notifyAll", "()V", new NativeMethod() {
            public void execute(Frame frame) {
            }
        });

    }
}
